package edu.ua.Team_Industry;
//
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

import android.content.Intent;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.LinearLayout;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

public class Industry_Map extends MapActivity {
	
	LinearLayout linearLayout;
	MapView mapView;
	private Location myLocation;
	private LocationManager imManager;
	private ImListener imListener;
	private MapController imController;
	private GeoPoint youPoint;
//	private Cursor cursor;
	
	
	private long tableid;
	private FTClient ftclient;
	
	List<Overlay> mapOverlays;
	Drawable gpsMe;
	Drawable redDot;
	Drawable blueDot;
	Drawable greenDot;
	Drawable yellowDot;
	Drawable purpleDot;
	GpsOverlay gpsOverlay;
	myMapOverlay mapOverlay;
	
	ArrayList<AreaOverlay> areaOverlays;
	DatabaseHelper dbHelper;
	public ArrayList<GeoPoint> areaTag = new ArrayList<GeoPoint>();
	ArrayList<PointTag> pointTags = new ArrayList<PointTag>();
    
    Boolean areaTagging = false;
    
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mapView = (MapView) findViewById(R.id.mapview);
        mapView.setBuiltInZoomControls(true);
        youPoint = null;
        imController = mapView.getController();
        mapOverlays = mapView.getOverlays();
        gpsMe = this.getResources().getDrawable(R.drawable.androidmarker);
        redDot = this.getResources().getDrawable(R.drawable.dot);
        gpsOverlay = new GpsOverlay(gpsMe); 
        mapOverlay = new myMapOverlay(redDot, this);

        areaOverlays = new ArrayList<AreaOverlay>();
        registerForContextMenu(mapView);
        
        tableid = 2203627;
        String token = ClientLogin.authorize("maptagger@gmail.com", "cs495industry");
        ftclient = new FTClient(token);
        dbHelper = new DatabaseHelper(this);
        
        try {
        	dbHelper.createDataBase();
        	dbHelper.openDataBase();
        	
        	ArrayList<PointTag> localRedTags = dbHelper.getAllPointTags();
        	
        	ArrayList<AreaTag> localRedAreas = dbHelper.getAllAreaTags();
        	
        	for (PointTag tag : localRedTags) {
        		pointTags.add(tag);	
        	}
        	
        	for (AreaTag tag: localRedAreas) {
        		areaOverlays.add(new AreaOverlay(tag.points, tag.color));
        		for (AreaOverlay overlay : areaOverlays) {
        			overlay.setMap(this);
        			GeoPoint center = overlay.getCenter();
        			OverlayItem overlayItem = new OverlayItem(center, Integer.toString(tag.color), "");
        			mapOverlay.addOverlay(overlayItem);
        		}
        	}
        	
        	for (PointTag tag : pointTags) {
        		GeoPoint point = new GeoPoint(tag.latitude, tag.longitude);
        		OverlayItem ovItem = new OverlayItem(point, Integer.toString(tag.color), tag.description);
				mapOverlay.addOverlay(ovItem);
        	}

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        
        imManager = (LocationManager) this.getSystemService(LOCATION_SERVICE);
        imListener = new ImListener();
        startListening();
        myLocation = imManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
        if (myLocation != null){
        	stopListening();
        	int lat = (int) (myLocation.getLatitude() * 1E6);
			int lng = (int) (myLocation.getLongitude() * 1E6);
			
			youPoint = new GeoPoint(lat, lng);
			imController.setZoom(14);
			imController.animateTo(youPoint);
			OverlayItem overlayitem = new OverlayItem(youPoint, "", "");
        	gpsOverlay.addOverlay(overlayitem);
        	mapOverlays.add(gpsOverlay);
        }
        else
        {
        	imController.setZoom(2);
        }
        mapOverlays.add(mapOverlay);
		mapView.postInvalidate();
		for (AreaOverlay overlay : areaOverlays) {
    			mapOverlays.add(overlay); 
    			mapView.postInvalidate();
    		}
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu){
    	super.onCreateOptionsMenu(menu);
    	MenuInflater inflater = getMenuInflater();
    	inflater.inflate(R.menu.menu, menu);
    	Menu m_menu = menu;
    	m_menu.add(Menu.NONE, Menu.FIRST+1, 2, "Filter");
    	return super.onCreateOptionsMenu(menu);
    }
    
    
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
    	Menu m = menu;
    	if (areaTagging) {
    		m.add(Menu.NONE, Menu.FIRST+1, 0, "Add more points");
    		m.add(Menu.NONE, Menu.FIRST+2, 0, "Finish");
    	}
    	else {
    		m.add(Menu.NONE, Menu.FIRST+4, 0,"Area");
    		m.add(Menu.NONE, Menu.FIRST+3, 0, "Point");
    		
    	}
    	m.add(Menu.NONE, Menu.FIRST+5, 0, "Cancel");
    }
    
    @Override
    public boolean onContextItemSelected(MenuItem item) {
      Random r = new Random();
      int tagId = r.nextInt();
      switch (item.getItemId()) {
      
      case Menu.FIRST+1:
    	  areaTag.add(mapOverlay.newPoint);
    	  return true;
    	  
      case Menu.FIRST+2:
    	  Intent myIntent = new Intent(this, InputInfo.class);
      	  startActivityForResult(myIntent, 0);
    	  return true;
          
      case Menu.FIRST+3:
    	  // add PointTag
    	  
		  // open activity to populate data
		  myIntent = new Intent(this, InputInfo.class);
          startActivityForResult(myIntent, 1);
      	  return true;
      	  
      case Menu.FIRST+4:
    	  // start areaTagging
    	  areaTag.clear();
    	  areaTag.add(mapOverlay.newPoint);
    	  areaTagging = true;
      	  return true;
      	  
      case Menu.FIRST+5:
    	  // Cancel
    	  return true;
    	  
      default:
        return super.onContextItemSelected(item);
      }
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
        case R.id.You:
        	if (myLocation != null){
            	stopListening();
            	gpsOverlay.removeAll();
            	int lat = (int) (myLocation.getLatitude() * 1E6);
    			int lng = (int) (myLocation.getLongitude() * 1E6);
    			youPoint = new GeoPoint(lat, lng);
    			imController.animateTo(youPoint);
    			OverlayItem overlayitem = new OverlayItem(youPoint, "", "");
            	gpsOverlay.addOverlay(overlayitem);
    			
            }
            else
            {
            	imController.setZoom(2);
            }
			return true;
			
//        case R.id.red_dot:
//        	selectedColor = 1;
//        	if(!mapOverlays.contains(mapOverlay)){
//        		mapOverlays.add(mapOverlay);
//        		mapView.postInvalidate();
//        	}
//        	else
//            {
//            	mapOverlays.remove(mapOverlay);
//            	mapOverlays.add(mapOverlay);
//            	mapView.postInvalidate();
//            }
//        	for (AreaOverlay overlay : areaOverlays) {
//        		if(!mapOverlays.contains(overlay)) {
//        			mapOverlays.add(overlay); 
//        			mapView.postInvalidate();
//        		}
//        		else
//        		{
//        			mapOverlays.remove(overlay);
//        			mapOverlays.add(overlay);
//        			mapView.postInvalidate();
//        		}
//        	}
//        	selectedOverlay = mapOverlay;
//        	return true;
        	
        	
        case R.id.Exit_Point:
        	mapOverlays.clear();
        	mapOverlays.add(gpsOverlay);
        	mapView.postInvalidate();
        	return true;
        	
        case R.id.Quit:
        	this.finish();
        	return true;
        	
        case Menu.FIRST+1:
        	Intent filterIntent = new Intent(this, Filter_Handler.class);
      	    startActivityForResult(filterIntent, 2);
      	    return true;
        	
        case R.id.Sync:
        	try {
        		ArrayList<PointTag> allPoints = dbHelper.getAllPointTags();

        		ArrayList<AreaTag> allAreas = dbHelper.getAllAreaTags();
        		
        		for(PointTag pt : allPoints) {

                String inID = Integer.toString(pt.id);
                String inDesc = pt.description;
                String inLat = Integer.toString(pt.latitude);
                String inLong = Integer.toString(pt.longitude);
                String inColor = Integer.toString(pt.color);
                String inPic = pt.picture;
                StringBuilder insert = new StringBuilder();
                insert.append("INSERT INTO ");
                insert.append(tableid);
                insert.append(" (ID, Description, Latitude, Longitude, Color, Date, Picture) VALUES ");
                insert.append("(");
                insert.append(inID);
                insert.append(", '");
                insert.append(inDesc);
                insert.append("', ");
                insert.append(inLat);
                insert.append(", ");
                insert.append(inLong);
                insert.append(", ");
                insert.append(inColor);
                insert.append(", ");
                insert.append(new Date().getDate()); //?
                insert.append(", '");
                insert.append(inPic);
                insert.append("')");

                ftclient.query(insert.toString());
        		}
        		
        		for (AreaTag at : allAreas) {
        			for (GeoPoint pt : at.points) {
        			String arID = Integer.toString(at.id);
                    String arLat = Integer.toString(pt.getLatitudeE6());
                    String arLong = Integer.toString(pt.getLongitudeE6());
                    String arColor = Integer.toString(at.color);
                    StringBuilder insertAreas = new StringBuilder();
                    insertAreas.append("INSERT INTO ");
                    insertAreas.append("2360869"); // Table Id for areaTags
                    insertAreas.append(" (ID, Latitude, Longitude, Color) VALUES ");
                    insertAreas.append("(");
                    insertAreas.append(arID);
                    insertAreas.append(", ");
                    insertAreas.append(arLat);
                    insertAreas.append(", ");
                    insertAreas.append(arLong);
                    insertAreas.append(", ");
                    insertAreas.append(arColor);
                    insertAreas.append(")");
                    

                    ftclient.query(insertAreas.toString());
        			}
        			
        		}
                
                // Save the data to Fusion Tables
        		StringBuilder selectPoints = new StringBuilder();
                selectPoints.append("SELECT * FROM ");
                selectPoints.append(tableid);
        		
        		String selectResult = ftclient.query(selectPoints.toString());
                
                String[] results = selectResult.split( "[\\n,*]"  );
                ArrayList<PointTag> ServerPoints = new ArrayList<PointTag>();
                for ( int i = 7; i< results.length; i = i+7 ) {
                	int lat = Integer.parseInt(results[i+2]);
                	int lng = Integer.parseInt(results[i+3]);
                	int color = (Integer.parseInt(results[i+4]));
                	PointTag point = new PointTag(lat, lng, color);
                	point.id = (Integer.parseInt(results[i]));
                    point.description = results[i+1];
                    point.picture = results[i+6];
                    Date date = new Date();
                    ServerPoints.add(point);
                }
                for (PointTag tag : ServerPoints) {
                dbHelper.addPointTag(tag);
                }
                
                for (PointTag tag : ServerPoints) {
            		GeoPoint point = new GeoPoint(tag.latitude, tag.longitude);
            		OverlayItem ovItem = new OverlayItem(point, Integer.toString(tag.color), tag.description);
            		mapOverlay.addOverlay(ovItem);
            	}
                
                StringBuilder selectAreas = new StringBuilder();
                selectAreas.append("SELECT * FROM ");
                selectAreas.append("2360869");
                
                String selectAreaResult = ftclient.query(selectAreas.toString());
                
                String[] areaResults = selectAreaResult.split( "[\\n,*]"  );
                ArrayList<AreaTag> ServerAreas = new ArrayList<AreaTag>();
                for ( int i = 4; i< areaResults.length; i = i+4 ) {
                	boolean found = false;
                	AreaTag area = new AreaTag(Integer.parseInt(areaResults[i]));
                	int lat = Integer.parseInt(areaResults[i+1]);
                	int lng = Integer.parseInt(areaResults[i+2]);
                	int color = (Integer.parseInt(areaResults[i+3]));
                	area.color = color;
                	for (AreaTag tag : ServerAreas) {
						if (tag.id == area.id) {
							found = true;
							tag.points.add(new GeoPoint(lat, lng));
						}
					}
                	if (!found) {
                		area.points.add(new GeoPoint(lat, lng));
                		ServerAreas.add(area);
                	}
                }
                
                for (AreaTag tag : ServerAreas) {
                    dbHelper.addAreaTag(tag);
                }
                
                for (AreaTag tag : ServerAreas) {
            		AreaOverlay ov = new AreaOverlay(tag.points, tag.color);
            		ov.setMap(this);
            			areaOverlays.add(ov);
            	}
                
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        	return true;
		
        default:
            return super.onOptionsItemSelected(item);
        }
    }
	
    
    @Override 
    public void onActivityResult(int requestCode, int resultCode, Intent data) {     
      super.onActivityResult(requestCode, resultCode, data); 
      switch(requestCode) { 
        case (0) : {
        	Random r = new Random();
            int tagId = r.nextInt();
            if (resultCode == RESULT_OK) { 
            String description = data.getStringExtra("DESCRIPTION");

            int tagType = data.getIntExtra("TAG_TYPE", 1);
        	ArrayList<GeoPoint> areaClone = (ArrayList<GeoPoint>) areaTag.clone();
        	areaClone.add(mapOverlay.newPoint);
        	AreaOverlay areaOv = new AreaOverlay(areaClone, tagType);
            areaOv.setMap(this);
            GeoPoint center = areaOv.getCenter();
      	  
            PointTag centerTag = new PointTag(center.getLatitudeE6(), center.getLongitudeE6(), tagType);
            centerTag.id = tagId;
            centerTag.color = tagType;
            centerTag.description = description;
            dbHelper.addPointTag(centerTag);
   
            AreaTag aTag = new AreaTag(centerTag.id);
            
            aTag.points = areaClone;
            aTag.color = tagType;
            OverlayItem overlayItem = new OverlayItem(center, Integer.toString(aTag.color), centerTag.description);
            mapOverlay.addOverlay(overlayItem);
            mapOverlays.add(areaOv);
            mapView.postInvalidate();
            dbHelper.addAreaTag(aTag);
            areaTagging = false;
            areaTag.clear();
            return;
            }
        }
      
        case (1) : { 
          Random r = new Random();
          int tagId = r.nextInt();
          if (resultCode == RESULT_OK) { 
          String description = data.getStringExtra("DESCRIPTION");
          int tagType = data.getIntExtra("TAG_TYPE", 1);
          
          GeoPoint singlePoint = mapOverlay.newPoint;
      	  
		  PointTag singleTag = new PointTag(singlePoint.getLatitudeE6(), singlePoint.getLongitudeE6(), tagId);
          singleTag.id = tagId;
          singleTag.description = description;
          singleTag.color = tagType;
          dbHelper.addPointTag(singleTag);
          OverlayItem overlayItem = new OverlayItem(singlePoint, Integer.toString(tagType), singleTag.description);
          mapOverlay.addOverlay(overlayItem);
		  mapView.postInvalidate();
          
    	  areaTagging = false;
      	  areaTag.clear();

          } 
          return;
        }
        
        case (2) : {
        	if (resultCode == RESULT_OK) {
        		mapOverlays.clear();
        		mapOverlay = new myMapOverlay(redDot, this);
        		areaOverlays = new ArrayList<AreaOverlay>();
        		ArrayList<PointTag> newTags = new ArrayList<PointTag>();
        		ArrayList<AreaTag> newAreaTags = new ArrayList<AreaTag>();
        		if(data.getBooleanExtra("Check_1", false)){
        			newTags.addAll(dbHelper.getPointTags(1));
        			newAreaTags.addAll(dbHelper.getAreaTags(1));
        		}
        		if(data.getBooleanExtra("Check_2", false)){
        			newTags.addAll(dbHelper.getPointTags(2));
        			newAreaTags.addAll(dbHelper.getAreaTags(2));
        		}
        		if(data.getBooleanExtra("Check_3", false)){
        			newTags.addAll(dbHelper.getPointTags(3));
        			newAreaTags.addAll(dbHelper.getAreaTags(3));
        		}
        		if(data.getBooleanExtra("Check_4", false)){
        			newTags.addAll(dbHelper.getPointTags(4));
        			newAreaTags.addAll(dbHelper.getAreaTags(4));
        		}
        		if(data.getBooleanExtra("Check_5", false)){
        			newTags.addAll(dbHelper.getPointTags(5));
        			newAreaTags.addAll(dbHelper.getAreaTags(5));
        		}
        		for(PointTag ptTag : newTags){
        			GeoPoint point = new GeoPoint(ptTag.latitude, ptTag.longitude);
        			OverlayItem ovItem = new OverlayItem(point, Integer.toString(ptTag.color), ptTag.description);
        			mapOverlay.addOverlay(ovItem);
        		}
        		//String descr = "";
        		for(AreaTag paTag: newAreaTags){
        			AreaOverlay aOv = new AreaOverlay(paTag.points, paTag.color);
        			aOv.areaTag = new AreaTag(paTag.id);
        			for(PointTag pointTag : newTags) {
    					if(pointTag.id == paTag.id) {
  						aOv.areaTag.description = pointTag.description;
   						break;
    					}
    				}
        			areaOverlays.add(aOv);
        			//String descr = "";
    				
        		}
        		for (AreaOverlay overlay : areaOverlays){
    				overlay.setMap(this);
    				GeoPoint center = overlay.getCenter();
    				OverlayItem overlayItem = new OverlayItem(center, Integer.toString(overlay.color), overlay.areaTag.description);
    				mapOverlay.addOverlay(overlayItem);
    			}
        		mapOverlays.add(gpsOverlay);
        		mapOverlays.add(mapOverlay);
        		for(AreaOverlay ov : areaOverlays){
        			mapOverlays.add(ov);
        		}
        		
        		mapView.postInvalidate();
        	}
        	
        	return;
        	  
          }
        } 
      } 
    
	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}
	
	@Override
    protected void onDestroy() {
        stopListening();
        super.onDestroy();
    }

    @Override
    protected void onPause() {
        stopListening();
        super.onPause();
    }

    @Override
    protected void onResume() {
        startListening();
        super.onResume();
    }
    
    private void startListening(){
    	imManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, imListener);
    }
    
    private void stopListening(){
    	if (imManager != null){imManager.removeUpdates(imListener);}
    }
    
    
    public class ImListener implements LocationListener {

    	@Override
    	public void onLocationChanged(Location location) {
    		myLocation = location;
    		
    	}

    	@Override
    	public void onProviderDisabled(String provider) {
    		
    	}

    	@Override
    	public void onProviderEnabled(String provider) {
    		
    	}

    	@Override
    	public void onStatusChanged(String provider, int status, Bundle extras) {
    		
    	}

    }
}